package com.lwl.blog.core.servlet;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.lwl.blog.core.constants.BaseConstants;
import com.lwl.blog.listener.ThymeleafListener;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class BaseServlet extends HttpServlet {
    //声明请求
    protected HttpServletResponse resp;
    protected HttpServletRequest req;

    public void myInit(){

    }
    @Override
    public void init() throws ServletException {
        ConvertUtils.register(new Converter() {
            public Object convert(Class type, Object value) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                try {
                    return simpleDateFormat.parse(value.toString());
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return null;
            }
        }, Date.class);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 给上面的req和resp赋值 --》这样干会出现线程安全的问题？先不考这个问题
        this.req = req;
        this.resp = resp;

        // 1.获取用户调用的action
        String action = getActionName(req.getRequestURI());

        // 2.判断action为空
        if (StringUtils.isEmpty(action)) {
            System.out.println("action不能为空");
            return;
        }

        // 3.根据actionName找到方法
        Method method = null;
        try {
            method = findActionMethod(action);
        } catch (NoSuchMethodException e) {
            System.out.println("在Servlet中没有找到【" + action + "】方法");
            return;
        }

        try {
            // 4.调用action方法
            String result = executeAction(method, req, resp);

            // 5.响应客户端
            if (!StringUtils.isEmpty(result)) {
                respClient(result, req, resp);
            }
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ServletException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void respClient(String r, HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        int index = r.indexOf(":");
        String type = r.substring(0, index);//获得跳转方式
        String page = r.substring(index + 1);//获得当前页面
        String contextPath = req.getContextPath();
        System.out.println(contextPath);
        if (BaseConstants.BASE_FORWARD.equals(type)) {
            req.getRequestDispatcher("/" + page).forward(req, resp);
        } else if (BaseConstants.BASE_REDIRECT.equals(type)) {
            resp.sendRedirect(contextPath + "/" + page);
        } else if (BaseConstants.BASE_SCRIPT.equals(type)) {
            // 以脚本形式提示用户
            resp.getWriter().write("<script>alert('" + page + "');</script>");
        } else if (BaseConstants.BASE_JSON.equals(type)) {
            resp.getWriter().write(page);
        }

    }

    // 执行方法
    private String executeAction(Method method, HttpServletRequest req, HttpServletResponse resp) throws InvocationTargetException, IllegalAccessException {
        return (String) method.invoke(this);
    }

    private Method findActionMethod(String action) throws NoSuchMethodException {
        return this.getClass().getMethod(action);
    }

    private String getActionName(String uri) {
        return uri.substring(uri.lastIndexOf("/") + 1);
    }

    public String outJson(Boolean flag) {

        Map<String, Object> map = new HashMap<>();
        map.put("code", 200); // 默认成功，200:成功，100：失败
        if (!flag) {
            map.put("code", 100); // 覆盖
            map.put("msg", "插入失败");
        }
        String jsonString = JSON.toJSONString(map);
        System.out.println("JSON:" + jsonString);

        return BaseConstants.BASE_JSON + ":" + jsonString;
    }

    public void outView(String viewName, Map<String, Object> data) throws Exception {
        //获得从上下问对象
        ServletContext context = req.getServletContext();
        TemplateEngine templateEngine = ThymeleafListener.getTemplateEngine(context);

        //获得themleaf的域对象,解析要用到的数据线存放到这个域对象中
        WebContext webContext = new WebContext(req, resp, context);
        //将数据存放到集合中
        webContext.setVariables(data);
        //处理模板数据,同时重定向将数据转发到页面
        templateEngine.process(viewName, webContext, resp.getWriter());


    }

    //帖子用户outjson方法
    public String outJson(Integer code,String msg){
        //创建一个集合
        Map<String,Object> map=new HashMap<>();
        //添加一个默认值，200响应成功
        map.put("code",200);
        if (code!=200){
            map.put("code",code);
        }
        //提示信息
        map.put("msg",msg);
        //转换json格式
        String s = JSON.toJSONString(map);

        return BaseConstants.BASE_JSON+":"+s;
    }

}
